package com.shu.framework.redis;

import com.shu.framework.utils.JsonUtil;
import com.shu.framework.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Set;
import java.util.concurrent.TimeUnit;
@Component
public class RedisService {
    private static final Logger LOGGER = LoggerFactory.getLogger(RedisService.class);
    /**只能操作string类型*/
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    /**可以操作object类型*/
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * string类型 设置方法
     * @param key
     * @param value
     */
    public <T> void set(KeyPrefix keyPrefix,String key,T value){
        try {
            if(StringUtils.isEmpty(key) || StringUtils.isNull(value)){
                return;
            }
            String str = JsonUtil.convertObj2String(value);
            if(keyPrefix.expireSeconds()<=0){
                stringRedisTemplate.opsForValue().set(getRealKey(keyPrefix,key),str);
            }else {
                stringRedisTemplate.opsForValue().set(getRealKey(keyPrefix,key), str, keyPrefix.expireSeconds(), TimeUnit.SECONDS);
            }
        } catch (Exception e) {
            LOGGER.error("set error",e);
        }
    }
    /**
     * string类型 获取方法
     * @param key
     * @return
     */
    public <T> T get(KeyPrefix keyPrefix,String key,Class<T> clazz){
        try {
            if(StringUtils.isEmpty(key) || StringUtils.isNull(clazz)){
                return null;
            }
            return  JsonUtil.convertString2Obj(stringRedisTemplate.opsForValue().get(getRealKey(keyPrefix,key)),clazz);
        } catch (Exception e) {
            LOGGER.error("set error",e);
            return null;
        }
    }

    /**
     * 直接key查询
     * @param key
     * @param clazz
     * @param <T>
     * @return
     */
    public <T> T get(String key,Class<T> clazz){
        try {
            if(StringUtils.isEmpty(key) || StringUtils.isNull(clazz)){
                return null;
            }
            return  JsonUtil.convertString2Obj(stringRedisTemplate.opsForValue().get(key),clazz);
        } catch (Exception e) {
            LOGGER.error("set error",e);
            return null;
        }
    }
    /**
     * 删除key
     * @param key
     */
    public void delete(KeyPrefix keyPrefix,String key){
        try {
            if(StringUtils.isEmpty(key) ){
                return;
            }
            stringRedisTemplate.delete(getRealKey(keyPrefix,key));
        } catch (Exception e) {
            LOGGER.error("set error",e);
        }
    }

    /**
     * 判断key是否存在
     * @param keyPrefix
     * @param key
     * @return
     */
    public boolean exits(KeyPrefix keyPrefix,String key){
        try {
            if(StringUtils.isEmpty(key) ){
                return false;
            }
            return stringRedisTemplate.hasKey(getRealKey(keyPrefix,key));
        } catch (Exception e) {
            LOGGER.error("set error",e);
            return false;
        }
    }

    /**
     * 加指定的数
     * @param keyPrefix
     * @param key
     * @param num
     * @return
     */
    public Long incr(KeyPrefix keyPrefix,String key,Integer num){
        try {
            if(StringUtils.isEmpty(key) || num==0){
                return 0l;
            }
            Long aLong =stringRedisTemplate.opsForValue().increment(getRealKey(keyPrefix,key),num);
            return aLong;
        } catch (Exception e) {
            LOGGER.error("set error",e);
            return 0l;
        }
    }
    /**
     * 加1
     * @param keyPrefix
     * @param key
     * @return
     */
    public Long incr(KeyPrefix keyPrefix,String key){
        try {
            if(StringUtils.isEmpty(key)){
                return 0l;
            }
            Long aLong =stringRedisTemplate.opsForValue().increment(getRealKey(keyPrefix,key),1);
            return aLong;
        } catch (Exception e) {
            LOGGER.error("set error",e);
            return 0l;
        }
    }

    /**
     * 减指定的数
     * @param keyPrefix
     * @param key
     * @param num
     * @return
     */
    public Long decr(KeyPrefix keyPrefix,String key,Integer num){
        try {
            if(StringUtils.isEmpty(key) || num==0){
                return 0l;
            }
            Long aLong = stringRedisTemplate.opsForValue().increment(getRealKey(keyPrefix,key),-num);
            return aLong;
        } catch (Exception e) {
            LOGGER.error("set error",e);
            return 0l;
        }
    }
    /**
     * 减一
     * @param keyPrefix
     * @param key
     * @return
     */
    public Long decr(KeyPrefix keyPrefix,String key){
        try {
            if(StringUtils.isEmpty(key)){
                return 0l;
            }
            Long aLong = stringRedisTemplate.opsForValue().increment(getRealKey(keyPrefix,key),-1);
            return aLong;
        } catch (Exception e) {
            LOGGER.error("set error",e);
            return 0l;
        }
    }

    public static String getRealKey(KeyPrefix keyPrefix,String key){
        String realKey=keyPrefix.getPrefix()+key;
        return realKey;
    }

    /**
     * 获取所有key值
     * @param keyPrefix
     * @return
     */
    public Set<String> keys(KeyPrefix keyPrefix) {
        Set<String> keys = stringRedisTemplate.keys(getRealKey(keyPrefix, "*"));
        return keys;
    }
}
